<template>
  <n-layout embedded>
    <n-space vertical size="small" align="center">
      <n-descriptions label-placement="left" separator=" "
                      title="敌人属性" :column="1" bordered>
        <n-descriptions-item label="防御">
          <n-space>
            <n-slider v-model:value="attr.def" :max="3000" />
            <n-input-number v-model:value="attr.def" :min="0" :show-button="false"/>
          </n-space>
        </n-descriptions-item>
        <n-descriptions-item label="法抗">
          <n-space>
            <n-slider v-model:value="attr.mr" :max="100" />
            <n-input-number v-model:value="attr.mr" :min="0" :show-button="false"/>
          </n-space>
        </n-descriptions-item>
        <n-descriptions-item label="数量">
          <n-space>
            <n-slider v-model:value="attr.count" :max="10" :min="1" />
            <n-input-number v-model:value="attr.count" :min="1" :show-button="false"/>
          </n-space>
        </n-descriptions-item>
        <n-descriptions-item label="查询敌人">
          <n-space>
            <n-select
              v-model:value="selectedEnemy" filterable
              placeholder="查询敌人" :options="optionsList"
              :loading="loading" clearable remote
              @search="handleSearch"
            />
          </n-space>
        </n-descriptions-item>
      </n-descriptions>
      <pre v-if="debug">
{{ props }}
      </pre>
    </n-space>
  </n-layout>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { computedAsync } from '@vueuse/core'
import { useI18n } from 'vue-i18n'
import { Maybe } from 'purify-ts/Maybe'
import { NTooltip, NButton, NCode, NSlider, NInputNumber,
         NSelect, NDescriptions, NDescriptionsItem, NSpace } from 'naive-ui'
import { apiGet } from '../utils'

// 传给该组件的参数，使用toRef取得响应式引用
// 值修改emit给上层组件
const props = defineProps({
  attr: {
    def: { type: Number, default: 0 },
    mr: { type: Number, default: 0 },
    count: { type: Number, default: 1 },
    enemyId: String
  },
  debug: { type: Boolean, default: false }
})

const emit = defineEmits({
  'update:attr': {
    def: Number,
    mr: Number,
    count: Number,
    enemyId: String
  }
})

// 双向绑定
const attr = ref({
  def: 0,
  mr: 0,
  count: 1,
  ...props.attr
})
emit('update:attr', attr.value) // 实际上改变了引用?

// script setup上下文中不能使用Vue.$t，必须单独引入
const { t, locale } = useI18n()
const selectedEnemy = ref(null)
const loading = ref(false)
const optionsList = ref([])

const updateNames = ref(false)
const enemyList = computedAsync(async () => {
    const ret = await apiGet(`view/enemyList/${locale.value}`)
    updateNames.value = true
    return ret
})

const enemyNames = computed(() => {
  updateNames.value = false // pivot
  if (enemyList.value) {
    const names = {} as any
    // 把敌人按显示名字分类
    enemyList.value.forEach(e => {
      if (!names[e.name])
        names[e.name] = [e]
      else 
        names[e.name].push(e)
    })
    const aliases = []
    for (let n in names) {
      let instance = 0  // 同名但不同ID的序号
      names[n].forEach(inst => {
        for (let lv = 0; lv < inst.levels; ++lv) {
          let alias: string = inst.name
          if (names[n].length > 1) alias += ` #${instance}`
          if (inst.levels > 1) alias += ` Lv${lv}`
          aliases.push({
            enemyId: inst.enemyId,
            name: inst.name,
            alias,
            lv
          })
        }
        ++instance
      })
    } // for names
    return aliases
  } else {
    return []
  }
})

const handleSearch = (query: string) => {
  if (!query.length) {
    optionsList.value = []
  } else {
    loading.value = true
    optionsList.value = enemyNames.value.filter(x => x.alias.toUpperCase().includes(query.toUpperCase()))
      .map(x => ({ label: x.alias, value: `${x.enemyId}|${x.lv}` }))
    loading.value = false
  }
}

const selectedEnemyAttr = computedAsync(async () => {
  if (selectedEnemy.value) {
    const unpack = selectedEnemy.value.split('|')
    const enemyId: string = unpack[0]
    const lv = parseInt(unpack[1])
    const attrs = await apiGet(`view/enemy/${locale.value}/${enemyId}`)
    const ret = {...attrs[0]}
    // 把等级n的属性覆盖到等级0上
    if (lv > 0 && lv < attrs.length) {
      //console.log(attrs[lv])
      for (let k in attrs[lv]) {
        if (attrs[lv][k] == null) {
          // pass
        } else if (typeof(attrs[lv][k]) === 'object') {
          for (let j in attrs[lv][k])
            ret[k][j] = attrs[lv][k][j]
        } else
          ret[k] = attrs[lv][k]
      }
    }
    return ret
  } else return null
})

watch(selectedEnemyAttr, (_new, _old) => {
  if (_new) {
    attr.value.def = _new.attributes.def
    attr.value.mr = _new.attributes.magicResistance
  }
})
</script>

<style scoped>
.n-slider {
  min-width: 200px;
}
.n-input-number {
  max-width: 70px;
}
</style>
